package lt.inkredibl.iit;

import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class TetragonIterable
	implements Iterable<Polygon2D>
{
	private Tetragon _t;
	private int _width;
	private int _height;

	public TetragonIterable(Tetragon t, int width, int height)
	{
		_t = t;
		_width = width;
		_height = height;
	}

	public Iterator<Polygon2D> iterator()
	{
		final Matrix<Point2D> matrix = split();
		
		return new Iterator<Polygon2D>()
		{
			int x = 0;
			int y = 0;
			
			public boolean hasNext()
			{
				return x < (matrix.getWidth()-1) && y < (matrix.getHeight()-1);
			}
			
			public Polygon2D next()
			{
				return new Polygon2D(new Point2D[] {matrix.get(x, y), matrix.get(x+1, y), matrix.get(x+1, y+1), matrix.get(x, y+1)});
			}
			
			public void remove()
			{
				throw new UnsupportedOperationException();
			}
		};
	}

	public Matrix<Point2D> split()
	{
		// left and right edge points
		List<Point2D> lPoints = _t.getLeftEdge().split(_height).getPoints();
		List<Point2D> rPoints = _t.getRightEdge().reverse().split(_height).getPoints();
		// horisontal lines split to _width segments
		List<Edge> hLines = new ArrayList<Edge>();
		
		for (int i = 0; i <= _height; i++)
		{
			Point2D pl = lPoints.get(i);
			Point2D pr = rPoints.get(i);
			hLines.add(Edge.valueOf(pl, pr).split(_width));
		}

		// top and bottom edge points
		List<Point2D> tPoints = _t.getTopEdge().split(_width).getPoints();
		List<Point2D> bPoints = _t.getBottomEdge().reverse().split(_width).getPoints();
		// vertical edges split to _height segments and transformed
//		List<Edge> vEdges = new ArrayList<Edge>();
		Matrix<Point2D> matrix = new Matrix<Point2D>(_width + 1, _height + 1);  

		for (int i = 0; i <= _width; i++)
		{
			List<Point2D> pts = new ArrayList<Point2D>();
			for (int j = 0; j <= _height; j++)
			{
				pts.add(hLines.get(j).getPoints().get(i));
			}
//			vEdges.add(Edge.valueOf(pts).stretch(bPoints.get(i), tPoints.get(i)));
			matrix.setCol(i, Edge.valueOf(pts).stretch(bPoints.get(i), tPoints.get(i)).getPoints());
		}
		
		return matrix;
	}

}
